import copy

from typing import List, Optional
from datetime import datetime, timedelta

from settings import Settings
from services.server_integration.alarm_db import AlarmDB
from services.automatic_control.api import AutomaticControlApi
from services.server_integration.api import ServerIntegrationApi
from services.server_integration.schemas.alarms import Alarm, ALARMS
from services.new_services.new_server_integration.schemas.block import Block
from services.server_integration.schemas.alarms_request import AlarmsRequest
from services.server_integration.schemas.unit_configuration import ChanelConfig
from common.third_party.save_config import save_config, load_config, load_const
from services.server_integration.schemas.calibrate_status import CalibrateHistory
from services.new_services.new_server_integration.schemas.time_gps import GpsTime
from services.new_services.new_server_integration.schemas.list_statuses import ListStatuses
from services.server_integration.schemas.full_unit_configuration import FullUnitConfiguration
from services.new_services.new_server_integration.schemas.alarm_configuration import DeleteAlarms
from services.new_services.new_server_integration.schemas.response_message import ResponseMessage
from services.new_services.new_server_integration.schemas.subblock import SubblocksNames, BlockWord
from services.new_services.new_server_integration.schemas.cities_timezones import get_city_by_timezone
from services.new_services.new_server_integration.schemas.alarms_request import NewAlarmsRequest, Filter
from services.server_integration.schemas.alarms_response_configuration import AlarmResponseConfiguration
from services.new_services.new_server_integration.schemas.enable_configuration import LinksConnectionType
from services.new_services.new_server_integration.schemas.carrier_freq_response import CarrierFrequencyResponse
from services.new_services.new_server_integration.cviya import _get_statuses_list_by_cviya, _get_config_by_cviya
from services.new_services.new_server_integration.schemas.full_unit_configuration import NewFullUnitConfiguration
from services.new_services.new_server_integration.schemas.available_connection import LinksConnections, Connection
from services.new_services.new_server_integration.schemas.common_configuration import CommonConfiguration, BlockType
from services.new_services.new_server_integration.schemas.rel_channel_con_status import RelayChannelConnectionStatusResponse
from services.new_services.new_server_integration.schemas.short_block_info import ShortBlockInfoResponse, SmsObject, RmsResponse, SmsResponse, OpticsResponse
from services.new_services.new_server_integration.schemas.channels_configuration import Attenuation, Delay, ServiceSubChannels, ServiceChannels, Subchannels, ChannelsConfiguration, ConnectionType, BlockMode


class NewServerIntegration:
    SI_API = ServerIntegrationApi()
    settings = Settings()

    __slots__ = ['alarm_db']

    def __init__(self) -> None:
        self.alarm_db = AlarmDB(self.settings.DATABASE_PATH + '/test.db')

    def load_new_full_config(self) -> NewFullUnitConfiguration:
        default = NewFullUnitConfiguration(
            common_configuration=CommonConfiguration(),
            channels_configuration=ChannelsConfiguration()
        )

        config: NewFullUnitConfiguration = load_config(
            'si/new_full_unit_config',
            NewFullUnitConfiguration,
            load_const(
                'new_full_unit_config',
                NewFullUnitConfiguration,
                default
            )
        )

        return config

    def save_only_new_full_config(self, config: NewFullUnitConfiguration):
        save_config('si/new_full_unit_config', config)

    async def upload_configuration(self, new_full_unit_config, user_role) -> ResponseMessage:

        current_full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))

        if current_full_unit_configuration.common_configuration.block_cviya != new_full_unit_config.common_configuration.block_cviya:
            return ResponseMessage(message='Ошибка: не совпадение ЦВИИ', status=False)
        else:
            await self.set_new_full_unit_config(new_full_unit_config=new_full_unit_config.dict(), user_role=user_role, upload_config=True)
            return ResponseMessage(message='Конфигурация сохранена', status=True)

    def compare_statuses(self, service_channels: tuple[ServiceChannels, ServiceChannels, ServiceChannels, ServiceChannels],
                         new_statuses_list: ListStatuses) -> ListStatuses:

        # ФУНКЦИЯ ЗАПОМИНАНИЯ РЕЖИМА ВКЛЮЧЕНИЯ И ВЫКЛЮЧЕНИЯ САБ-КАНАЛОВ ПРИ СМЕНЕ РЕЖИМА БЛОКА
        # ( WB, 2G И Т.Д.)

        current_statuses = ListStatuses()

        # ПОЛУЧАЕМ СТАТУС ВКЛЮЧЕННЫХ КАНАЛОВ ПО САБ КАНАЛАМ ЕСЛИ FSC
        # ПОТОМУ ЧТО В FSC ОНИ ЗАВИСИМЫ ДРУГ ОТ ДРУГА
        # В FSR УПРАВЛЯЮТСЯ ОТДЕЛЬНО, БЕРЁМ ИЗ СЕРВИСНЫХ КАНАЛОВ

        for index, channel in enumerate(service_channels):
            current_statuses.sms_statuses_list.append(channel.enabled)

        # ПОЛУЧАЕМ СТАТУСЫ EARFCN И ARFCN
        for index, channel in enumerate(service_channels):
            if index > 1:
                current_statuses.arfcn_statuses_list.append(channel.service_subchannels.enabled_arfcn)
                current_statuses.earfcn_statuses_list.append(channel.service_subchannels.enabled_earfcn)

        # ЕСЛИ НОВЫЙ СТАТУС НЕ NONE, ЗНАЧИТ ВОЗВРАЩАЕМ ФЛАГ КОТОРЫЙ БЫЛ СДЕЛАН ПОЛЬЗОВАТЕЛЕМ

        compared_statuses: list = [[], [], []]

        for main_index, (current_model_field, new_model_field) in enumerate(zip(current_statuses, new_statuses_list)):
            for current_status, new_status in zip(current_model_field[1], new_model_field[1]):
                if new_status is False and current_status is None:
                    compared_statuses[main_index].append(new_status)
                elif new_status is not None:
                    compared_statuses[main_index].append(current_status)
                else:
                    compared_statuses[main_index].append(new_status)

        return ListStatuses(sms_statuses_list=compared_statuses[0], earfcn_statuses_list=compared_statuses[1], arfcn_statuses_list=compared_statuses[2])

    def change_channels(self, service_channels: List[ServiceChannels], statuses_by_cviya, subchannels: List[Subchannels],
                        block_type, block_mode, block_cviya) -> tuple[List[ServiceChannels], List[Subchannels]]:
        # КОМПАНУЕМ ФЛАГИ ПО ТЕКУЩИМ И НОВЫМ ФЛАГАМ КАНАЛОВ

        statuses = self.compare_statuses(service_channels, statuses_by_cviya)

        # ОБНОВЛЯЕМ ФЛАГИ В САБ КАНАЛАХ. ЕСЛИ СЕРВИСНЫЙ NONE, ТО САБ КАНАЛ ТОЖЕ
        # И В FSR В РЕЖИМЕ WB_2G И 2G БЛОКИРУЕМ 2 ИЛИ 2 И 3 КАНАЛЫ СООТВЕТСТВЕННО
        for subchannel_index, subchannel in enumerate(subchannels):
            if statuses.sms_statuses_list[subchannel_index] is None:
                subchannel.enabled = None
            if block_type == BlockType.FSR:
                if block_mode == BlockMode.WB_2G:
                    if subchannel_index in [1, 2]:
                        subchannel.enabled = None
                elif block_mode == BlockMode.G2:
                    if subchannel_index == 2:
                        subchannel.enabled = None
                # ЕСЛИ РЕЖИМ WB, ТО ОТКРЫВАЮ ДОСТУП, ДЕЛАЮ ЕГО FALSE
                else:
                    if subchannel.enabled is None:
                        subchannel.enabled = False
            # ЕСЛИ РЕЖИМ 2G, ТО НАдо В ЧЕТВЁРТОМ САБ-КАНАЛЕ ЗНАЧЕНИЕ СДЕЛАТЬ 10 ПРИНУДИТЕЛЬНО
            if block_mode == BlockMode.G2:
                if subchannel_index == 3:
                    subchannel.fields.bandwidth.bandwidth_ul = 10
        # ОБНОВЛЯЕМ ФЛАГИ В СЕРВИСНЫХ КАНАЛАХ ВСЕГДА ЕСЛИ ТИП БЛОКА FSC
        # ИЛИ
        # ОБНОВЛЯЕМ ФЛАГИ В FSR В РЕЖИМАХ WB + 2G, 2G
        if block_type == BlockType.FSC or block_mode in [BlockMode.WB_2G, BlockMode.G2]:
            for channel_index, channel in enumerate(service_channels):
                if channel.enabled is not None:
                    channel.enabled = statuses.sms_statuses_list[channel_index]
                elif block_cviya == 'ЦВИЯ.Сервисная':
                    channel.enabled = statuses.sms_statuses_list[channel_index]

        # ОБНОВЛЯЕМ АРФСН'ы И ЕАРФСН'ы
        local_index = 0
        for index, channel in enumerate(service_channels):

            # ЭТО ПОЛЕ ЕСТЬ ТОЛЬКО В СЕРВИСНЫХ КАНАЛАХ 2 И 3, ПОЭТОМУ ПЕРВЫЕ ДВА СКИПАЕМ
            if index > 1:
                channel.service_subchannels.enabled_arfcn = statuses.arfcn_statuses_list[local_index]
                channel.service_subchannels.enabled_earfcn = statuses.earfcn_statuses_list[local_index]
                local_index += 1

        return service_channels, subchannels

    def change_modes(self, full_unit_configuration: NewFullUnitConfiguration, block_mode) -> dict | ResponseMessage:

        # НОВЫЕ СТАТУСЫ ЭТО ТЕ КОТОРЫЕ ДОЛЖНЫ БЫТЬ ПО ЦВИЕ И РЕЖИМУ БЛОКА
        # (WB, WB + 2G И 2G)

        service_channels = full_unit_configuration.channels_configuration.service_channels
        subchannels = full_unit_configuration.channels_configuration.subchannels

        block_type = full_unit_configuration.common_configuration.block_type
        block_cviya = full_unit_configuration.common_configuration.block_cviya

        # В ЗАВИСИМОСТИ ОТ РЕЖИМА БЛОКА БЛОКИРУЕМ КАНАЛЫ
        # ВОЗВРАЩАЕМ ИХ ЗНАЧЕНИЯ МАССИВОМ BOOL
        statuses_by_cviya: ListStatuses | ResponseMessage = _get_statuses_list_by_cviya(full_unit_configuration.channels_configuration.service_channels[2].enabled,
                                                                                       full_unit_configuration.channels_configuration.service_channels[3].enabled,
                                                                                       block_type, block_cviya, block_mode)

        if type(statuses_by_cviya) is ResponseMessage:
            return statuses_by_cviya

        service_channels, subchannels = self.change_channels(service_channels, statuses_by_cviya, subchannels, block_type, block_mode, block_cviya)

        # ОБНОВЛЯЕМ ТЕКУЩУЮ КОНФИГУ НЕ СОХРАНЯЯ
        full_unit_configuration.channels_configuration.service_channels = service_channels
        full_unit_configuration.channels_configuration.subchannels = subchannels

        final_config = self.pop_attenuation_and_subchannels(full_unit_configuration.dict())

        return final_config

    async def change_block_mode(self, block_mode):

        # В ЗАВИСИМОСТИ ОТ ТИПА БЛОКА, ЕГО ЦВИИ, БЛОКИРУЕМ НУЖНЫЕ КАНАЛЫ
        full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))

        final_config = self.change_modes(full_unit_configuration, block_mode)

        return final_config

    async def enable_radio_or_optics(self, connection_types: LinksConnectionType, user_role: str) -> bool:
        full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))

        # ЕСЛИ НИЧЕГО НЕ ВЫБРАЛ И НАЖАЛ СОХРАНИТЬ, ВЫКЛЮЧАЕМ СФП И РМЫ NONE
        if connection_types.link_1 == ConnectionType.EMPTY:
            full_unit_configuration.channels_configuration.relay_channels[0].enabled = None
            full_unit_configuration.common_configuration.sfp_statuses.sfp_1_enabled = False

            full_unit_configuration.channels_configuration.relay_channels[0].connection_type = ConnectionType.EMPTY

        # ЕСЛИ ВКЛЮЧЕН РМ, ТО РАЗРЕШАЕМ РМ И ВЫКЛЮЧАЕМ СФП
        elif connection_types.link_1 == ConnectionType.RADIO:
            if full_unit_configuration.channels_configuration.relay_channels[0].enabled is True:
                pass
            else:
                full_unit_configuration.channels_configuration.relay_channels[0].enabled = False
            full_unit_configuration.common_configuration.sfp_statuses.sfp_1_enabled = False

            full_unit_configuration.channels_configuration.relay_channels[0].connection_type = ConnectionType.RADIO

        # ЕСЛИ ВКЛЮЧЕНА ОПТИКА, ТО ВЫКЛЮЧАЕМ РМ И ВКЛЮЧАЕМ ОПТИКУ
        elif connection_types.link_1 == ConnectionType.OPTICS:
            full_unit_configuration.channels_configuration.relay_channels[0].enabled = None
            full_unit_configuration.common_configuration.sfp_statuses.sfp_1_enabled = True

            full_unit_configuration.channels_configuration.relay_channels[0].connection_type = ConnectionType.OPTICS

        # ЕСЛИ НИЧЕГО НЕ ВЫБРАЛ И НАЖАЛ СОХРАНИТЬ
        if connection_types.link_2 == ConnectionType.EMPTY:
            full_unit_configuration.channels_configuration.relay_channels[1].enabled = None
            full_unit_configuration.common_configuration.sfp_statuses.sfp_2_enabled = False

            full_unit_configuration.channels_configuration.relay_channels[1].connection_type = ConnectionType.EMPTY

        # ЕСЛИ ВКЛЮЧЕН РМ, ТО РАЗРЕШАЕМ РМ И ВЫКЛЮЧАЕМ СФП
        elif connection_types.link_2 == ConnectionType.RADIO:
            if full_unit_configuration.channels_configuration.relay_channels[1].enabled is True:
                pass
            else:
                full_unit_configuration.channels_configuration.relay_channels[1].enabled = False
            full_unit_configuration.common_configuration.sfp_statuses.sfp_2_enabled  = False

            full_unit_configuration.channels_configuration.relay_channels[1].connection_type = ConnectionType.RADIO

        # ЕСЛИ ВКЛЮЧЕНА ОПТИКА, ТО ВКЛЮЧАЕМ ОПТИКУ И ВЫКЛЮЧАЕМ РМ
        elif connection_types.link_2 == ConnectionType.OPTICS:
            full_unit_configuration.channels_configuration.relay_channels[1].enabled = None
            full_unit_configuration.common_configuration.sfp_statuses.sfp_2_enabled  = True

            full_unit_configuration.channels_configuration.relay_channels[1].connection_type = ConnectionType.OPTICS

        await self.set_new_full_unit_config(full_unit_configuration.dict(), user_role)

        return True

    def rename_time_to_start_time(self, alarms_object: dict):
        alarms = alarms_object.get('alarms')
        for alarm in alarms:
            alarm['start_time'] = alarm.pop('time')
            alarm['id'] = alarm.pop('aid')

        alarms_object['alarms'] = alarms

        return alarms_object

    def _get_alarms_filters(self, request: NewAlarmsRequest) -> AlarmsRequest:
        old_alarms_request: AlarmsRequest = AlarmsRequest()

        if request.sort_by == 'start_time':
            request.sort_by = 'time'
        elif request.sort_by == 'id':
            request.sort_by = 'aid'

        filter: Filter
        for filter in request.filters:
            if Filter(key='group', value='Minor') in request.filters and Filter(key='group', value='Critical') in request.filters :
                request.filters.remove(Filter(key='group', value='Minor'))
                request.filters.remove(Filter(key='group', value='Critical'))
            elif filter.value == 'Critical':
                filter.key = 'is_warning'
                filter.value = False
            elif filter.value == 'Minor':
                filter.key = 'is_warning'
                filter.value = True

        old_alarms_request.sort_by = request.sort_by
        old_alarms_request.order = request.order
        old_alarms_request.start_date = datetime.fromtimestamp(request.start_date)
        old_alarms_request.filters = request.filters
        old_alarms_request.end_date = datetime.fromtimestamp(request.end_date)
        old_alarms_request.offset = request.offset
        old_alarms_request.count = request.count
        old_alarms_request.language = request.language

        return old_alarms_request


    async def get_log_alarms(self, request: NewAlarmsRequest, user_role):
        old_alarms_request: AlarmsRequest = self._get_alarms_filters(request)

        result = self.rename_time_to_start_time(await self.SI_API.get_alarms_log(old_alarms_request, user_role))

        return result

    async def get_current_alarms(self, request: NewAlarmsRequest, user_role):
        si_api = ServerIntegrationApi()
        old_alarms_request: AlarmsRequest = self._get_alarms_filters(request)

        si_api_object = await si_api.get_current_alarms(old_alarms_request, user_role)
        alarms: AlarmResponseConfiguration = AlarmResponseConfiguration(**si_api_object)
        result = self.rename_time_to_start_time(alarms.dict())

        return result

    def get_channels_flag(self, full_unit_configuration):
        rm_1_enabled = full_unit_configuration.channels_configuration.relay_channels[0].enabled
        rm_2_enabled = full_unit_configuration.channels_configuration.relay_channels[1].enabled

        sfp_1_enabled = full_unit_configuration.common_configuration.sfp_statuses.sfp_1_enabled
        sfp_2_enabled = full_unit_configuration.common_configuration.sfp_statuses.sfp_2_enabled

        rm_statuses = [sfp_1_enabled if rm_1_enabled is None else rm_1_enabled,
                       sfp_2_enabled if rm_2_enabled is None else rm_2_enabled]

        sm_statuses = [
            full_unit_configuration.channels_configuration.service_channels[0].enabled,
            full_unit_configuration.channels_configuration.service_channels[1].enabled,
            full_unit_configuration.channels_configuration.service_channels[2].enabled,
            full_unit_configuration.channels_configuration.service_channels[3].enabled
        ]

        return rm_statuses, sm_statuses

    async def get_subblocks_statuses(self):
        full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))

        rm_statuses, sm_statuses = self.get_channels_flag(full_unit_configuration)

        return {"rm_statuses": rm_statuses, "sm_statuses": sm_statuses}

    def get_channels_enable_status(self, full_unit_configuration):
        rm_statuses = [full_unit_configuration.channels_configuration.relay_channels[0].enabled,
                       full_unit_configuration.channels_configuration.relay_channels[1].enabled]

        sm_statuses = [full_unit_configuration.channels_configuration.service_channels[0].enabled,
                       full_unit_configuration.channels_configuration.service_channels[1].enabled,
                       full_unit_configuration.channels_configuration.service_channels[2].enabled,
                       full_unit_configuration.channels_configuration.service_channels[3].enabled]

        sfp_statuses = [full_unit_configuration.common_configuration.sfp_statuses.sfp_1_enabled,
                        full_unit_configuration.common_configuration.sfp_statuses.sfp_2_enabled]

        block_type = full_unit_configuration.common_configuration.block_type

        return rm_statuses, sm_statuses, sfp_statuses, block_type

    async def get_telemetry(self, user_role):
        full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))
        all_telemetry = await self.SI_API.get_technical_status()

        if user_role != 'adjuster':
            all_telemetry.gps_telemetry.time_type.is_need = False

        if user_role == 'server':
            all_telemetry.mark_is_invalid_from_server()
            for sm_telemetry in all_telemetry.sm_telemetry:
                sm_telemetry.pap.is_need = False

        elif user_role == 'user':
            all_telemetry.mark_is_invalid_from_user()
            for sm_telemetry in all_telemetry.sm_telemetry:
                sm_telemetry.pap.is_need = False

        all_telemetry = all_telemetry.dict()

        # СЛОВАРЬ В КОТОРЫЙ ЗАПИХАЕМ КОНЕЧНУЮ ТЕЛЕМЕТРИЮ
        total_telemetry_dict = {}

        # УБИРАЕМ ТО ЧТО ВООБЩЕ НЕ ИСПОЛЬЗУЕТСЯ
        all_telemetry.pop('sensors')
        all_telemetry.pop('ocb_states')
        all_telemetry.pop('statuses')

        # ПОЛУЧАЕМ СТАТУСЫ КАНАЛОВ ПО ДЖСОНУ
        (rm_enable_statuses, sm_enable_statuses,
         sfp_enable_statuses, block_type) = self.get_channels_enable_status(full_unit_configuration)

        # БЕЖИМ ПО ТЕЛЕМЕТРИИ
        for telemetry_name, telemetry_value in all_telemetry.items():

            # ЕСЛИ СПИСОК РМ ИЛИ СМ ИЛИ СФП, ТО НУЖНО ЕЩЁ FOR ПОВЕРХ
            if type(telemetry_value) is list:
                prom_list = []
                telemetry_dict = {}

                # СЧЁТЧИК ОШИБОК
                incorrect_values = 0

                prom_dict = {}
                telemetry_copy = copy.deepcopy(telemetry_value)
                for index, channel_telemetry in enumerate(telemetry_value):

                    # СОЗДАЁМ СЛОВАРЬ ЗНАЧЕНИЙ ПО ПЕРВОМУ КАНАЛУ
                    if index == 0:
                        keys = list(channel_telemetry.keys())
                        prom_dict = {key: [] for key in keys}

                    for current_channel_telemetry_dict in channel_telemetry:

                        # УБИРАЕМ САБ ГРУППУ, НЕ ИСПОЛЬЗУЕТСЯ
                        telemetry_copy[index].get(f'{current_channel_telemetry_dict}').pop('subgroup')

                        # ЕСЛИ ЗНАЧЕНИЕ НЕКОРРЕКТНОЕ УВЕЛИЧИВАЕМ СЧЁТЧИК
                        if channel_telemetry.get(f'{current_channel_telemetry_dict}').get('is_incorrect') is True:
                            incorrect_values += 1

                        # ЕСЛИ СТОИТ ФЛАГ НЕ НУЖЕН. ТО УБИРАЕМ ИЗ ТЕЛЕМЕТРИИ ЭТОТ ОБЪЕКТ ДЛЯ ФРОНТА
                        if channel_telemetry.get(f'{current_channel_telemetry_dict}').get('is_need') is False:
                            telemetry_copy[index].pop(f'{current_channel_telemetry_dict}')

                        # ИНАЧЕ СТОИТ ФЛАГ НУЖЕН.
                        # А ТАК КАК НУЖЕН, ТО ЭТО ПОЛЕ, ПО КОТОРОМУ ОПРЕДЕЛЯЕМ НУЖЕН ИЛИ НЕ НУЖЕН, МОЖНО УБРАТЬ
                        else:
                            telemetry_copy[index].get(f'{current_channel_telemetry_dict}').pop('is_need')

                        # ТАК КАК ПОПАЕМ ТЕ ЗНАЧЕНИЯ КОТОРЫЕ НЕ НУЖНЫ
                        if telemetry_copy[index].get(f'{current_channel_telemetry_dict}') is not None:
                            prom_dict.get(current_channel_telemetry_dict).append(
                                telemetry_copy[index].get(f'{current_channel_telemetry_dict}'))
                        else:
                            try:
                                prom_dict.pop(current_channel_telemetry_dict)
                            except KeyError as e:
                                pass

                    # ВЫБИРАЕМ КАКОЙ СПИСОК ИСПОЛЬЗОВАТЬ
                    if telemetry_name == 'rm_telemetry':
                        enabled_status = rm_enable_statuses
                    else:
                        enabled_status = sm_enable_statuses

                    # ДОБАВЛЯЕМ ФЛАГ ВКЛЮЧЕН КАНАЛ ИЛИ НЕТ
                    telemetry_copy[index]['enabled'] = enabled_status[index]

                    # ДОБАВЛЯЕМ ТЕЛЕМЕТРИЮ ПО ИНДЕКСУ В НОВЫЙ СПИСОК С ТЕЛЕМЕТРИЕЙ
                    prom_list.append(telemetry_copy[index])

                # СОСТАВЛЯЕМ НОВЫЙ СЛОВАРЬ ДЛЯ ФРОНТА
                telemetry_dict['incorrect_values'] = incorrect_values

                # ЕСЛИ ТЕЛЕМЕТРИЯ РМ ИЛИ СФП
                if telemetry_name in ['rm_telemetry', 'sfp_telemetry']:

                    # ЕСЛИ ТЕЛЕМЕТРИЯ РМ
                    if telemetry_name == 'rm_telemetry':

                        # ЕСЛИ ХОТЬ ОДИН РМ ВКЛЮЧЕН, ТО СТАТУС True (МОЖНО ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                        if True in rm_enable_statuses:
                            telemetry_dict['status'] = True

                        # ЕСЛИ ОБА РМА ВЫКЛЮЧЕНЫ, ТО СТАТУС False (НЕЛЬЗЯ ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                        elif rm_enable_statuses[0] is False and rm_enable_statuses[1] is False:
                            telemetry_dict['status'] = False

                    # ЕСЛИ ТЕЛЕМЕТРИЯ СФП
                    elif telemetry_name == 'sfp_telemetry':

                        # ЕСЛИ ХОТЬ ОДИН СФП ВКЛЮЧЕН, ТО СТАТУС True (МОЖНО ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                        if True in sfp_enable_statuses:
                            telemetry_dict['status'] = True

                        # ЕСЛИ ОБА СФП ВЫКЛЮЧЕНЫ, ТО СТАТУС False (НЕЛЬЗЯ ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                        elif sfp_enable_statuses[0] is False and sfp_enable_statuses[1] is False:
                            telemetry_dict['status'] = False

                # ИНАЧЕ ТЕЛЕМЕТРИЯ SM
                else:

                    # ЕСЛИ ХОТЬ ОДИН СМ ВКЛЮЧЕН, ТО СТАТУС True (МОЖНО ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                    if True in sm_enable_statuses:
                        telemetry_dict['status'] = True

                    # ЕСЛИ ВСЕ СМЫ ВЫКЛЮЧЕНЫ, ТО СТАТУС False (НЕЛЬЗЯ ПОСМОТРЕТЬ ТЕЛЕМЕТРИЮ)
                    elif (sm_enable_statuses[0] is False and sm_enable_statuses[1] is False and
                          sm_enable_statuses[2] is False and sm_enable_statuses[3] is False):
                        telemetry_dict['status'] = False

                telemetry_dict['values'] = prom_dict

                # ДОБАВЛЯЕМ СОСТАВЛЕННЫЙ СЛОВАРЬ В ФИНАЛЬНЫЙ СЛОВАРЬ
                total_telemetry_dict[f'{telemetry_name}'] = telemetry_dict

            # ИНАЧЕ ПРОСТО ПРОХОДИМСЯ ПО ПОВЕР, GPS И ЦОС
            else:

                # СЧЁТЧИК ОШИБОК
                incorrect_values = 0

                keys = list(telemetry_value.keys())
                prom_dict = {key: [] for key in keys}

                telemetry_copy = copy.deepcopy(telemetry_value)
                for current_channel_telemetry_dict in telemetry_value:

                    # УБИРАЕМ САБ ГРУППУ, НЕ ИСПОЛЬЗУЕТСЯ
                    telemetry_copy.get(f'{current_channel_telemetry_dict}').pop('subgroup')

                    # ЕСЛИ ЗНАЧЕНИЕ НЕКОРРЕКТНОЕ УВЕЛИЧИВАЕМ СЧЁТЧИК
                    if telemetry_value.get(f'{current_channel_telemetry_dict}').get('is_incorrect') is True:
                        incorrect_values += 1

                    # ЕСЛИ СТОИТ ФЛАГ НЕ НУЖЕН. ТО УБИРАЕМ ИЗ ТЕЛЕМЕТРИИ ЭТОТ ОБЪЕКТ ДЛЯ ФРОНТА
                    if telemetry_value.get(f'{current_channel_telemetry_dict}').get('is_need') is False:
                        telemetry_copy.pop(f'{current_channel_telemetry_dict}')

                    # ИНАЧЕ СТОИТ ФЛАГ НУЖЕН.
                    # А ТАК КАК НУЖЕН, ТО ЭТО ПОЛЕ, ПО КОТОРОМУ ОПРЕДЕЛЯЕМ НУЖЕН ИЛИ НЕ НУЖЕН, МОЖНО УБРАТЬ
                    else:
                        telemetry_copy.get(f'{current_channel_telemetry_dict}').pop('is_need')

                    # ДЕЙСТВУЕТ ТОЛЬКО ДЛЯ РМ И СМ, ТК ТАМ МОЖНО КАНАЛЫ ВЫКЛЮЧАТЬ
                    # НО ПО ШАБЛОНУ ДЛЯ ФРОНТА НУЖНО ЧТОБЫ ОН БЫЛ В КАЖДОЙ ТЕЛЕМЕТРИИ
                    telemetry_copy['enabled'] = True

                    if telemetry_copy.get(f'{current_channel_telemetry_dict}') is not None:
                        prom_dict.get(current_channel_telemetry_dict).append(
                            telemetry_copy.get(f'{current_channel_telemetry_dict}'))
                    else:
                        try:
                            prom_dict.pop(current_channel_telemetry_dict)
                        except KeyError as e:
                            pass

                # СОЕДИНЯЕМ ЦИФРЫ С БУКВОЙ В СТРОКУ В GPS
                if telemetry_name == 'gps_telemetry':
                    prom_dict.get('latitude')[0][
                        'value'] = f"{str(prom_dict.get('north_south')[0].get('value'))} {str(prom_dict.get('latitude')[0].get('value'))}"
                    prom_dict.pop('north_south')
                    prom_dict.get('longitude')[0][
                        'value'] = f"{str(prom_dict.get('east_west')[0].get('value'))} {str(prom_dict.get('longitude')[0].get('value'))}"
                    prom_dict.pop('east_west')

                # TODO IS_INCORRECT TRUE FALSE NONE
                # СОСТАВЛЯЕМ НОВЫЙ СЛОВАРЬ ДЛЯ ФРОНТА
                # СТАТУС МЕНЯЕТСЯ ДЛЯ РМОВ, СФП И СМОВ. ОСТАЛЬНОЕ ВСЕГДА True
                telemetry_dict = {
                    'incorrect_values': incorrect_values,
                    'status': True,
                    'values': prom_dict
                }

                # ДОБАВЛЯЕМ ЕГО В ФИНАЛЬНЫЙ СЛОВАРЬ
                total_telemetry_dict[f'{telemetry_name}'] = telemetry_dict

        # ЦИКЛ ДОБАВЛЕНИЯ ЕДИНИЦ ИЗМЕРЕНИЯ
        # БЕЖИМ ПО ТЕЛЕМЕТРИИ
        for telemetry_name, telemetry_value in total_telemetry_dict.items():

            # ПОЛУЧАЕМ СПИСОК ТЕЛЕМЕТРИИ
            telemetry = telemetry_value.get('values')

            # ДЛЯ КАЖДОГО ПОЛЯ ТЕЛЕМЕТРИИ
            for channel_telemetry in telemetry_value.get('values'):

                # ПОЛУЧАЕМ СПИСОК ЭТОЙ ТЕЛЕМЕТРИИ СО ВСЕХ КАНАЛОВ
                current_channel_telemetry = telemetry.get(f'{channel_telemetry}')

                # ЗАХОДИМ В КАЖДЫЙ КАНАЛ
                for index, local_telemetry in enumerate(current_channel_telemetry):

                    # ЕСЛИ КАНАЛ НЕ ПОСЛЕДНИЙ. ТО УДАЛЯЕМ У НЕГО ЕДИНИЦУ ИЗМЕРЕНИЯ
                    if not index + 1 == len(current_channel_telemetry):
                        local_telemetry.pop('measurement_name')

                # ДОБАВЛЯЕМ В СПИСОК ТЕЛЕМЕТРИИ С КАЖДОГО КАНАЛА НОВЫЙ ОБЪЕКТ - ЕДИНИЦУ ИЗМЕРЕНИЯ
                # ЕДИНИЦУ ИЗМЕРЕНИЯ БЕРЁМ КАК РАЗ С ПОСЛЕДНЕГО ОБЪЕКТА В КАЖДОМ КАНАЛЕ
                current_channel_telemetry.append(
                    {'value': current_channel_telemetry[len(current_channel_telemetry) - 1].get('measurement_name'),
                     'is_incorrect': False})

                # ТЕПЕРЬ НУЖНО УБРАТЬ ЭТУ ЕДИНИЦУ ИЗМЕРЕНИЯ ИЗ ПОСЛЕДНЕГО ОБЪЕКТА
                # ЕСЛИ ОБЪЕКТ 1 (НЕТ КАНАЛОВ КАК В РМ, СМ И СФП), ТО БЕРЁМ ПО ИНДЕКСУ -1 ОТ ДЛИНЫ
                # ЕСЛИ ОБЪЕКТОВ БОЛЬШЕ ЧЕМ 1. ТО БЕРЁМ ПО ИНДЕКСУ -2 ОТ ДЛИНЫ
                pop_index = len(current_channel_telemetry) - 1 if len == 1 else len(current_channel_telemetry) - 2
                current_channel_telemetry[pop_index].pop('measurement_name')

        total_telemetry_dict['block_type'] = full_unit_configuration.common_configuration.block_type

        return total_telemetry_dict

    def get_available_connection(self, block_cviya) -> LinksConnections | ResponseMessage:
        # СОЗДАЁМ ФУНКЦИЮ СОЗДАНИЯ ОБЪЕКТА, КОТОРЫЙ НЕОБХОДИМО ПЕРЕДАВАТЬ НА ФРОНТ

        if 'ЦВИЯ.' not in block_cviya:
            block_cviya = 'ЦВИЯ.' + block_cviya

        block_config: Block | ResponseMessage = _get_config_by_cviya(block_cviya)

        if type(block_config) is ResponseMessage:
            return block_config

        return LinksConnections(link_1_available_connection=Connection(radio=block_config.radio_connection[0],
                                                                       optics=block_config.optics_connection[0]),
                                link_2_available_connection=Connection(radio=block_config.radio_connection[1],
                                                                       optics=block_config.optics_connection[1]))

    async def _get_error_or_warning(self, alarm: Alarm) -> BlockWord:
        from services.server_integration.schemas.alarms import AlarmDescription
        descriptions: list[AlarmDescription] = [AlarmDescription(**desc) for desc in (await self.SI_API.load_alarms_descriptions())]

        if descriptions[alarm.code].is_warning:
            return BlockWord.WARNING
        else:
            return BlockWord.ERRORS

    async def _check_errors(self, subblock_name: str, current_alarms: list[Alarm]) -> BlockWord:

        alarm: Alarm
        for alarm in current_alarms:

            # ОБРЕЗАЕМ НАЗВАНИЕ АВАРИИ С КОНЦА, ЧТОБЫ УБРАТЬ ИНДЕКС
            # ТАК КАК В АВАРИЯХ ПОД ОБЩИЕ СУББЛОКИ

            if subblock_name[:-1] in [SubblocksNames.RM, SubblocksNames.SM, SubblocksNames.OPTIC]:

                # ЕСЛИ ЕСТЬ АВАРИЯ С ТАКИМ СУББЛОКОМ, ТО СМОТРИ ДАЛЬШЕ
                # ЕСЛИ САБ ГРУППА ТАКОЙ АВАРИИ СООТВЕТСТВУЕТ ПРОВЕРЯЕМОМУ СУБ БЛОКУ
                # ТО ЗНАЧИТ АВАРИЯ

                if subblock_name == alarm.subgroup:
                    # ЕСЛИ АВАРИЯ НАШЛАСЬ, ТО ВОЗВРАЩАЕМ АВАРИЮ

                    return await self._get_error_or_warning(alarm)

            # А В НЕКОТОРЫХ АВАРИЯХ НЕТ ИНДЕКСА КОНКРЕТНОГО СУБ БЛОКА
            # ВСЁ ПИШЕТСЯ В ГРУППУ
            # ЕСЛИ НЕПОНЯТНО ПОСМОТРЕТЬ JSON АВАРИЙ

            elif subblock_name == alarm.group:

                # ЕСЛИ АВАРИЯ НАШЛАСЬ, ТО ОСТАЛЬНЫЕ АВАРИИ НЕТ СМЫСЛА ПРОВЕРЯТЬ

                return await self._get_error_or_warning(alarm)

        # ЕСЛИ АВАРИЙ НЕТ
        else:
            return BlockWord.NOERRORS

    async def _get_word(self, channel_enabled_flag, subblock_word, current_alarms: list[Alarm]) -> str:

        # ЕСЛИ НАН ТО НЕТ ОШИБОК
        if channel_enabled_flag is None:
            word = BlockWord.NOERRORS

        # ИНАЧЕ СМОТРИМ АВАРИИ
        else:
            word = await self._check_errors(subblock_word, current_alarms)

        return word

    async def _build_sms(self, block_cviya, block_type, service_channels, current_alarms: list[Alarm], block_mode) -> SmsResponse | ResponseMessage:

        # ОБЪЯВЛЯЕМ МАССИВ
        sms = []

        # В БЛОКЕ FSR ИНДЕКСЫ КАНАЛОВ СООТВЕТСТВУЮТ СУББЛОКАМ НА ГЛАВНОМ ЭКРАНЕ
        if block_type == BlockType.FSR:

            saved_new_full_config = self.load_new_full_config()
            current_sms_statuses = [channel.enabled for channel in saved_new_full_config.channels_configuration.service_channels]

            for index, channel in enumerate(service_channels):

                # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                enabled: bool = channel.enabled
                frequency: float = channel.frequency
                editable: bool = channel.editable
                channel_index: int = index + 1

                # В FSR МОЖЕМ РУКАМИ ДОБАВЛЯТЬ СМЫ. ПО ЭТОМУ СМОТРИМ ПО СОХРАНЁННОЙ КОНФИГЕ
                # ЕСЛИ ТАМ ЗАПИСАН NONE, ТО БЛОКИРУЕМ

                if current_sms_statuses[index] is None:
                    sms.append(SmsObject(state=BlockWord.NOERRORS, value=None, editable=editable))
                else:

                    # СТРОИМ СЛОВО ПОИСКА
                    subblock_index_word = f'SM{channel_index}'

                    # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                    word = await self._get_word(enabled, subblock_index_word, current_alarms)

                    sms.append(SmsObject(state=word, value=frequency, editable=editable))

            # ТАК КАК СМОВ НА ФРОНТЕ 6, А НА БЕКЕ ТОЛЬКО 4, ДОПОЛНЯЕМ ИСКУССТВЕННО
            while len(sms) < 6:
                sms.append(SmsObject(state=BlockWord.BLOCKED, value=None, editable=False))

            return SmsResponse(statuses_list=sms)

        # В БЛОКЕ FSC ИНДЕКСЫ КАНАЛОВ НЕ СООТВЕТСТВУЮТ СУББЛОКАМ НА ГЛАВНОМ ЭКРАНЕ
        elif block_type == BlockType.FSC:

            statuses: ListStatuses | ResponseMessage = _get_statuses_list_by_cviya(service_channel_3_enabled=False,
                                                                                  service_channel_4_enabled=False,
                                                                                  block_type=BlockType.FSC,
                                                                                  block_cviya=block_cviya,
                                                                                  block_mode=block_mode)
            block_config: Block | ResponseMessage = _get_config_by_cviya(block_cviya)

            if type(statuses) is ResponseMessage:
                return statuses
            elif type(block_config) is ResponseMessage:
                return block_config

            sm_statuses = statuses.sms_statuses_list

            # ПОЛУЧАЕМ КОЛИЧЕСТВО SM
            sm_count = block_config.sms_count

            # У ЦВИИ С ДВУМЯ SM (BS НАЗЫВАЕТСЯ В FSC) ИНДЕКСЫ ОДНИ:
            # 1 КАНАЛ НА СТРАНИЦЕ КАНАЛОВ - ЭТО SM1 (BS1) НА ГЛАВНОМ ЭКРАНЕ
            # 4 КАНАЛ НА СТРАНИЦЕ КАНАЛОВ - ЭТО SM2 (BS2) НА ГЛАВНОМ ЭКРАНЕ

            # У ЦВИИ С ТРЕМЯ SM (BS НАЗЫВАЕТСЯ В FSC) ИНДЕКСЫ ДРУГИЕ:
            # 1 КАНАЛ НА СТРАНИЦЕ КАНАЛОВ - ЭТО SM1 (BS1) НА ГЛАВНОМ ЭКРАНЕ
            # 2 КАНАЛ НА СТРАНИЦЕ КАНАЛОВ - ЭТО SM2 (BS2) НА ГЛАВНОМ ЭКРАНЕ
            # 4 КАНАЛ НА СТРАНИЦЕ КАНАЛОВ - ЭТО SM3 (BS3) НА ГЛАВНОМ ЭКРАНЕ

            # МЕНЯЕМ ДЛЯ ФРОНТА ИНДЕКСЫ
            # ОТ КОЛИЧЕСТВА СМОВ МЕНЯЕТСЯ ИНДЕКС ВОЗВРАЩАЕМЫХ БЛОКОВ НА ГЛАВНЫЙ ЭКРАН
            # ТАК КАК ФИЗИЧЕСКИ ОНИ ПОДЦЕПЛЕНЫ ПО РАЗНОМУ
            # ЕСЛИ НЕПОНЯТНО СПРОСИТЬ У АЙРАТА

            if sm_count == 2:

                for index, channel in enumerate(service_channels):

                    # БЕРЁМ ЧАСТОТУ И ФЛАГ КАНАЛА. ЧАСТОТА НУЖНА ДЛЯ ФРОНТА
                    enabled: bool = channel.enabled
                    frequency: float = channel.frequency
                    editable: bool = channel.editable

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    if index + 1 == 1:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 1

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:
                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 4:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 4

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # ОСТАЛЬНЫЕ ИНДЕКСЫ СКИПАЕМ, СМОВ ПОД ТАКУЮ ЦВИЮ НЕТ, ОНИ НЕ НУЖНЫ, НО В КОНФИГЕ ЕСТЬ ВСЕГДА

                # ТАК КАК СМОВ НА ФРОНТЕ 6, А НА БЕКЕ ТОЛЬКО 4, ДОПОЛНЯЕМ ИСКУССТВЕННО
                # ПЛЮС ДОБАВЛЯЕМ ТЕ, КОТОРЫЕ ПРОСКИПАНЫ

                while len(sms) < 6:
                    sms.append(SmsObject(state=BlockWord.BLOCKED, value=None, editable=False))

                return SmsResponse(statuses_list=sms)

            elif sm_count == 3:

                for index, channel in enumerate(service_channels):

                    # БЕРЁМ ЧАСТОТУ И ФЛАГ КАНАЛА. ЧАСТОТА НУЖНА ДЛЯ ФРОНТА
                    enabled: bool = channel.enabled
                    frequency: float = channel.frequency
                    editable: bool = channel.editable

                    # ЕСЛИ КАНАЛ ЗАБЛОКИРОВАН ИЗ-ЗА ВЫБРАННОГО РЕЖИМА (WB, WB + 2G, 2G)
                    # ТО ДЕЛАЕМ ЕМУ СТАТУС ЗАБЛОКИРОВАН И ЗАПРЕЩАЕМ РЕДАКТИРОВАТЬ

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    if index + 1 == 1:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 1

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 2:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 2

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 4:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 4

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # ОСТАЛЬНЫЕ ИНДЕКСЫ СКИПАЕМ, СМОВ ПОД ТАКУЮ ЦВИЮ НЕТ, ОНИ НЕ НУЖНЫ, НО В КОНФИГЕ ЕСТЬ ВСЕГДА

                # ТАК КАК СМОВ НА ФРОНТЕ 6, А НА БЕКЕ ТОЛЬКО 4, ДОПОЛНЯЕМ ИСКУССТВЕННО
                # ПЛЮС ДОБАВЛЯЕМ ТЕ, КОТОРЫЕ ПРОСКИПАНЫ
                while len(sms) < 6:
                    sms.append(SmsObject(state=BlockWord.BLOCKED, value=None, editable=False))

                return SmsResponse(statuses_list=sms)

            elif sm_count == 4:
                for index, channel in enumerate(service_channels):

                    # БЕРЁМ ЧАСТОТУ И ФЛАГ КАНАЛА. ЧАСТОТА НУЖНА ДЛЯ ФРОНТА
                    enabled: bool = channel.enabled
                    frequency: float = channel.frequency
                    editable: bool = channel.editable

                    # ЕСЛИ КАНАЛ ЗАБЛОКИРОВАН ИЗ-ЗА ВЫБРАННОГО РЕЖИМА (WB, WB + 2G, 2G)
                    # ТО ДЕЛАЕМ ЕМУ СТАТУС ЗАБЛОКИРОВАН И ЗАПРЕЩАЕМ РЕДАКТИРОВАТЬ

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    if index + 1 == 1:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 1

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 2:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 2

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 3:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 3

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # INDEX + 1 ПОТОМУ ЧТО ИНДЕКСАЦИЯ ОТ 0, А НУМЕРАЦИЯ НАЧИНАЕТСЯ С 1
                    elif index + 1 == 4:

                        # ПОЛУЧАЕМ ЧАСТОТУ БЛОКА И ЕГО СТАТУС (ВКЛЮЧЕН, ВЫКЛЮЧЕН ИЛИ ОТСУТСТВУЕТ)
                        # ИЗ КОНФИГИ БЛОКА, КОТОРАЯ ПЕРВЫЙ РАЗ СОЗДАЁТСЯ ПО ЕГО ЦВИЕ
                        # В ДАЛЬНЕЙШЕМ, КОГДА БЛОК СОЗДАН, МЫ БЕРЁМ ВСЕ НАСТРОЙКИ ПО ЕГО КОНФИГЕ
                        channel_index = 4

                        if sm_statuses[index] is None:
                            sms.append(SmsObject(state=BlockWord.BLOCKED, value=frequency, editable=False))
                        else:

                            # СТРОИМ СЛОВО ПОИСКА
                            subblock_index_word = f'SM{channel_index}'

                            # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                            word = await self._get_word(enabled, subblock_index_word, current_alarms)

                            sms.append(SmsObject(state=word, value=frequency, editable=editable))

                    # ОСТАЛЬНЫЕ ИНДЕКСЫ СКИПАЕМ, СМОВ ПОД ТАКУЮ ЦВИЮ НЕТ, ОНИ НЕ НУЖНЫ, НО В КОНФИГЕ ЕСТЬ ВСЕГДА

                # ТАК КАК СМОВ НА ФРОНТЕ 6, А НА БЕКЕ ТОЛЬКО 4, ДОПОЛНЯЕМ ИСКУССТВЕННО
                # ПЛЮС ДОБАВЛЯЕМ ТЕ, КОТОРЫЕ ПРОСКИПАНЫ
                while len(sms) < 6:
                    sms.append(SmsObject(state=BlockWord.BLOCKED, value=None, editable=False))

                return SmsResponse(statuses_list=sms)

            else:
                return ResponseMessage(status=False, message="Количество СМОВ в коде не соответствует количеству СМОВ по ЦВИЯ")
        else:
            return ResponseMessage(status=False, message="Тип блока не FSC и не FSR")

    async def _build_rms(self, sfp_statuses, relay_channels, current_alarms) -> RmsResponse:

        # ОБЪЯВЛЯЕМ МАССИВ, КУДА БУДЕМ ЗАПИСЫВАТЬ ФЛАГИ СОСТОЯНИЯ КАЖДОГО РМА
        rms = []

        for index in range(0, len(relay_channels)):

            # ПО ДЛИНЕ JSON'A С РМАМИ ПОЛУЧАЕМ СОСТОЯНИЕ
            channel = relay_channels[index]
            rm_enabled = channel.enabled
            channel_index = index + 1

            optic_enabled = getattr(sfp_statuses, f'sfp_{channel_index}_enabled')

            # ЕСЛИ РМА НЕТ, ИЛИ ВКЛЮЧЕНА ОПТИКА
            if rm_enabled is None or optic_enabled is True:
                rms.append(BlockWord.DISABLED)

            # ЕСЛИ РМ ВЫКЛЮЧЕН
            elif rm_enabled is False:
                rms.append(BlockWord.DISABLED)

            # ИНАЧЕ ПРОВЕРЯЕМ НА ОШИБКИ
            else:

                # СТРОИМ СЛОВО ПОИСКА
                subblock_index_word = f'RM{channel_index}'

                # ПОЛУЧАЕМ ЕСТЬ ОШИБКИ ИЛИ НЕТ
                word = await self._get_word(rm_enabled, subblock_index_word, current_alarms)

                rms.append(word)

        return RmsResponse(statuses_list=rms)

    async def _build_optic(self, sfp_statuses, rm_statuses: RmsResponse, current_alarms) -> OpticsResponse:

        # СОСТОЯНИЕ ОПТИКИ СТРОИМ В ЗАВИСИМОСТИ ОТ СОСТОЯНИЯ РМОВ
        optics = []

        for index, rm in enumerate(rm_statuses.statuses_list):

            # ЕСЛИ РМ ЗАБЛОКИРОВАН ИЛИ ВЫКЛЮЧЕН ЗНАЧИТ ВКЛЮЧЕНА ОПТИКА И ТАМ МОГУТ БЫТЬ ОШИБКИ
            if rm == BlockWord.BLOCKED or rm == BlockWord.DISABLED:

                channel_index = index + 1

                # ЧИТАЕМ ФЛАГ ОПТИКИ. ОНА ИЛИ ВКЛЮЧЕНА ИЛИ НЕТ
                optic_enabled = getattr(sfp_statuses, f'sfp_{channel_index}_enabled')

                # ИНАЧЕ ПРОВЕРЯЕМ ОШИБКИ ПО ОПТИКЕ С ДРУГИМ ИНДЕКСОМ
                if optic_enabled is True:
                    word = await self._check_errors(f'Optic{channel_index}', current_alarms)

                # ЕСЛИ ВЫКЛЮЧЕНА ФЛАГ ЗАБЛОКИРОВАНА
                else:
                    word = BlockWord.DISABLED

            # ЕСЛИ РМ НЕ ЗАБЛОКИРОВАН, ЗНАЧИТ ОН ВКЛЮЧЕН, А СФП ЗАБЛОКИРОВАН
            else:
                word = BlockWord.DISABLED

            optics.append(word)

        return OpticsResponse(statuses_list=optics)

    async def get_block_info(self, user_role, language) -> ShortBlockInfoResponse | ResponseMessage:

        # ЕСЛИ ФЛАГ True ТО ТЕХНИК, ИНАЧЕ ЮЗЕР. ДЛЯ АВАРИЙ, ТАК КАК РАЗДЕЛЯЕМ
        user_role = 'adjuster' if user_role == 'technic' else user_role

        alarms_object: AlarmResponseConfiguration = AlarmResponseConfiguration(**(await self.SI_API.get_current_alarms(AlarmsRequest(count=self.settings.SERVER_INTEGRATION_ALARMS_COUNT, end_date=datetime(2036, 1, 1, 0, 0)), user_role)))
        current_alarms: list[Alarm] = alarms_object.alarms

        full_unit_configuration = self.load_new_full_config()

        str_timezone = ''
        timezone = full_unit_configuration.common_configuration.timezone
        if timezone == 0:
            str_timezone = 0
        elif timezone > 0:
            str_timezone = f'( UTC +{timezone} )'
        elif timezone < 0:
            str_timezone = f'( UTC -{timezone} )'

        city_by_timezone = get_city_by_timezone(timezone, language) + f' {str_timezone}'

        block_type = full_unit_configuration.common_configuration.block_type
        block_name = full_unit_configuration.common_configuration.block_config.block_info.block_name
        block_number = full_unit_configuration.common_configuration.block_config.block_info.serial_number
        block_cviya = full_unit_configuration.common_configuration.block_cviya[5:]
        sim_ip = full_unit_configuration.common_configuration.block_config.modem_config.sim_ip
        server_ip = str(full_unit_configuration.common_configuration.block_config.config.server_ip)
        block_ip = str(full_unit_configuration.common_configuration.block_config.config.block_ip)
        mac = full_unit_configuration.common_configuration.block_config.block_info.mac_address

        service_channels = full_unit_configuration.channels_configuration.service_channels
        sfp_statuses = full_unit_configuration.common_configuration.sfp_statuses
        relay_channels = full_unit_configuration.channels_configuration.relay_channels

        block_mode = full_unit_configuration.channels_configuration.block_mode

        sms_object: SmsResponse | ResponseMessage = await self._build_sms(full_unit_configuration.common_configuration.block_cviya, block_type, service_channels, current_alarms, block_mode)

        if isinstance(sms_object, ResponseMessage):
            return sms_object

        rms_object: RmsResponse = await self._build_rms(sfp_statuses, relay_channels, current_alarms)
        optics_object: OpticsResponse = await self._build_optic(sfp_statuses, rms_object, current_alarms)
        power: BlockWord = await self._check_errors(SubblocksNames.POWER, current_alarms)
        modem: BlockWord = await self._check_errors(SubblocksNames.MODEM, current_alarms)
        dsp: BlockWord = await self._check_errors(SubblocksNames.DSP, current_alarms)
        gps: BlockWord = await self._check_errors(SubblocksNames.GPS, current_alarms)
        sms_indexes: list = _get_config_by_cviya(full_unit_configuration.common_configuration.block_cviya).sms_index

        connection_type_link_1 = relay_channels[0].connection_type
        connection_type_link_2 = relay_channels[1].connection_type

        response: ShortBlockInfoResponse = ShortBlockInfoResponse(
            city=city_by_timezone,
            block_type=block_type,
            block_name=block_name,
            block_number=block_number,
            block_cviya=block_cviya,
            sim_ip=sim_ip,
            server_ip=server_ip,
            block_ip=block_ip,
            mac=mac,
            sms=sms_object.statuses_list,
            rm1=rms_object.statuses_list[0],
            rm2=rms_object.statuses_list[1],
            optic1=optics_object.statuses_list[0],
            optic2=optics_object.statuses_list[1],
            power=power,
            modem=modem,
            dsp=dsp,
            gps=gps,
            connection_type_link_1=connection_type_link_1,
            connection_type_link_2=connection_type_link_2,
            sms_indexes=sms_indexes
        )

        return response

    async def get_block_version(self):
        full_unit_configuration = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))
        return full_unit_configuration.common_configuration.block_config.block_info.version_info

    def convert_new_block_mode_to_old(self, block_mode: str) -> ChanelConfig:
        if block_mode == BlockMode.WB:
            return ChanelConfig.LTE
        elif block_mode == BlockMode.WB_2G:
            return ChanelConfig.LTE_GSM
        elif block_mode == BlockMode.G2:
            return ChanelConfig.GSM

    def set_convert_common_config(self, current_full_unit_config: FullUnitConfiguration, new_full_unit_config: NewFullUnitConfiguration, user_role: str, upload_config: bool = False) -> FullUnitConfiguration:

        current_full_unit_config.alarm_config.modem_alarm = new_full_unit_config.common_configuration.alarm_config.modem_alarm
        current_full_unit_config.alarm_config.server_alarm = new_full_unit_config.common_configuration.alarm_config.server_alarm

        current_full_unit_config.alarm_config.sfp[0] = new_full_unit_config.common_configuration.sfp_statuses.sfp_1_enabled
        current_full_unit_config.alarm_config.sfp[1] = new_full_unit_config.common_configuration.sfp_statuses.sfp_2_enabled

        current_full_unit_config.alarm_config.sensors[0].enabled = new_full_unit_config.common_configuration.alarm_config.sensor_1_enabled
        current_full_unit_config.alarm_config.sensors[0].normal_state = new_full_unit_config.common_configuration.alarm_config.sensor_1_normal_state
        current_full_unit_config.alarm_config.sensors[1].enabled = new_full_unit_config.common_configuration.alarm_config.sensor_2_enabled
        current_full_unit_config.alarm_config.sensors[1].normal_state = new_full_unit_config.common_configuration.alarm_config.sensor_2_normal_state

        current_full_unit_config.unit_configuration.block_name = new_full_unit_config.common_configuration.block_config.block_info.block_name

        if user_role == 'adjuster' and not upload_config:
            current_full_unit_config.unit_configuration.main_module.serial_number = new_full_unit_config.common_configuration.block_config.block_info.serial_number
            current_full_unit_config.unit_configuration.main_module.mac_address = new_full_unit_config.common_configuration.block_config.block_info.mac_address

        current_full_unit_config.unit_configuration.device.ip = new_full_unit_config.common_configuration.block_config.config.block_ip
        current_full_unit_config.unit_configuration.device.port = new_full_unit_config.common_configuration.block_config.config.block_port
        current_full_unit_config.unit_configuration.device.gateway = new_full_unit_config.common_configuration.block_config.config.gateway
        current_full_unit_config.unit_configuration.device.netmask = new_full_unit_config.common_configuration.block_config.config.netmask
        current_full_unit_config.unit_configuration.server.ip = new_full_unit_config.common_configuration.block_config.config.server_ip
        current_full_unit_config.unit_configuration.server.port = new_full_unit_config.common_configuration.block_config.config.server_port

        current_full_unit_config.modem.apn = new_full_unit_config.common_configuration.block_config.modem_config.apn.replace(',', '.')
        current_full_unit_config.modem.password = new_full_unit_config.common_configuration.block_config.modem_config.password
        current_full_unit_config.modem.ping_address = new_full_unit_config.common_configuration.block_config.modem_config.ping_address
        current_full_unit_config.modem.user = new_full_unit_config.common_configuration.block_config.modem_config.user

        current_full_unit_config.unit_configuration.cviya = new_full_unit_config.common_configuration.block_cviya
        current_full_unit_config.unit_configuration.unit_type = new_full_unit_config.common_configuration.block_type
        current_full_unit_config.unit_configuration.timezone = new_full_unit_config.common_configuration.timezone

        current_full_unit_config.unit_configuration.calibration_state = new_full_unit_config.common_configuration.calibration_config.calibration_state
        current_full_unit_config.unit_configuration.simulation_state = new_full_unit_config.common_configuration.calibration_config.simulation_state
        current_full_unit_config.unit_configuration.ustirovka_state = new_full_unit_config.common_configuration.calibration_config.ustirovka_state

        return current_full_unit_config

    def set_convert_channel_config(self, current_full_unit_config: FullUnitConfiguration, new_full_unit_config: NewFullUnitConfiguration, user_role: str) -> FullUnitConfiguration:

        # ПЕРЕВОДИМ НОВЫЙ JSON В СТАРЫЙ
        current_full_unit_config.unit_configuration.ac_link_tx = new_full_unit_config.channels_configuration.auto_gain_enabled
        current_full_unit_config.unit_configuration.ac_service_tx = new_full_unit_config.channels_configuration.auto_gain_enabled
        current_full_unit_config.unit_configuration.channel_3_and_4_config = self.convert_new_block_mode_to_old(new_full_unit_config.channels_configuration.block_mode)

        current_full_unit_config.service_channels[0].str.carrier_frequency.ul = new_full_unit_config.channels_configuration.carrier_frequency[0].fields.carrier_frequency_ul
        current_full_unit_config.service_channels[0].str.carrier_frequency.dl = new_full_unit_config.channels_configuration.carrier_frequency[0].fields.carrier_frequency_dl

        current_full_unit_config.service_channels[2].str.carrier_frequency.ul = new_full_unit_config.channels_configuration.carrier_frequency[1].fields.carrier_frequency_ul
        current_full_unit_config.service_channels[2].str.carrier_frequency.dl = new_full_unit_config.channels_configuration.carrier_frequency[1].fields.carrier_frequency_dl

        # ЗАПИСЫВАЕМ В СТАРЫЙ JSON, В МАССИВ ИЗ ЧЕТЫРЁХ РМОВ - ЗНАЧЕНИЯ ПЕРВОГО И ВТОРОГО РМА ИЗ НОВОГО КОНФИГА
        # ПОТОМУ ЧТО ЭТИ ЗНАЧЕНИЯ В СТАРОМ JSON В РАЗНЫХ МЕСТАХ БЕРУТСЯ ИЗ РАЗНЫХ ИНДЕКСОВ РМОВ - ПО ЭТОМУ ПИШЕМ ВО ВСЕ
        for channel_index in range(0, 4):
            for rtrs_index in range(0, 2):
                current_full_unit_config.relay_channels[channel_index].rtr_common.rt_rxs_enabled[rtrs_index] = bool(new_full_unit_config.channels_configuration.relay_channels[rtrs_index].enabled)
                current_full_unit_config.relay_channels[channel_index].rtrs[rtrs_index].central_frequency.ul = new_full_unit_config.channels_configuration.relay_channels[rtrs_index].fields.central_frequency_tx
                current_full_unit_config.relay_channels[channel_index].rtrs[rtrs_index].central_frequency.dl = new_full_unit_config.channels_configuration.relay_channels[rtrs_index].fields.central_frequency_rx
                current_full_unit_config.relay_channels[channel_index].rtrs[rtrs_index].output_power_link.input_gain = new_full_unit_config.channels_configuration.relay_channels[rtrs_index].fields.input_gain
                current_full_unit_config.relay_channels[channel_index].rtrs[rtrs_index].output_power_link.output_gain = new_full_unit_config.channels_configuration.relay_channels[rtrs_index].fields.output_gain
                current_full_unit_config.relay_channels[channel_index].rtrs[rtrs_index].output_power_link.output_power = new_full_unit_config.channels_configuration.relay_channels[rtrs_index].fields.output_power

            current_full_unit_config.relay_channels[channel_index].rtr_common.enabled.ul = bool(new_full_unit_config.channels_configuration.subchannels[channel_index].enabled)
            current_full_unit_config.relay_channels[channel_index].rtr_common.enabled.dl = bool(new_full_unit_config.channels_configuration.subchannels[channel_index].enabled)
            current_full_unit_config.relay_channels[channel_index].rtr_common.bandwidth.ul = new_full_unit_config.channels_configuration.subchannels[channel_index].fields.bandwidth.bandwidth_ul
            current_full_unit_config.relay_channels[channel_index].rtr_common.bandwidth.dl = new_full_unit_config.channels_configuration.subchannels[channel_index].fields.bandwidth.bandwidth_ul
            current_full_unit_config.relay_channels[channel_index].rtr_common.frequency_offset.ul = new_full_unit_config.channels_configuration.subchannels[channel_index].fields.frequency_offset.frequency_offset_ul
            current_full_unit_config.relay_channels[channel_index].rtr_common.frequency_offset.dl = new_full_unit_config.channels_configuration.subchannels[channel_index].fields.frequency_offset.frequency_offset_ul

            current_full_unit_config.service_channels[channel_index].editable = new_full_unit_config.channels_configuration.service_channels[channel_index].editable
            current_full_unit_config.service_channels[channel_index].str.enabled = bool(new_full_unit_config.channels_configuration.service_channels[channel_index].enabled)
            current_full_unit_config.service_channels[channel_index].frequency = new_full_unit_config.channels_configuration.service_channels[channel_index].frequency

            # 2G BANDWIDTH SET TO 10 TO 3,4 SERVICE CHANNEL
            if current_full_unit_config.unit_configuration.channel_3_and_4_config == ChanelConfig.GSM:
                if channel_index in [2, 3]:
                    current_full_unit_config.service_channels[channel_index].bandwidth = 10
                else:
                    current_full_unit_config.service_channels[channel_index].bandwidth = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.bandwidth
            else:
                current_full_unit_config.service_channels[channel_index].bandwidth = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.bandwidth

            current_full_unit_config.service_channels[channel_index].str.output_power = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.bs_power
            current_full_unit_config.service_channels[channel_index].frequency_offset.ul = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.frequency_offset.frequency_offset_ul
            current_full_unit_config.service_channels[channel_index].frequency_offset.dl = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.frequency_offset.frequency_offset_ul
            current_full_unit_config.service_channels[channel_index].str.gain.ul = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.gain.gain_ul
            current_full_unit_config.service_channels[channel_index].str.gain.dl = new_full_unit_config.channels_configuration.service_channels[channel_index].fields.gain.gain_dl

            # ТОЛЬКО У ВТОРОГО И ТРЕТЬЕГО СМА ЕСТЬ ЭТИ ПОЛЯ
            if channel_index > 1:
                current_full_unit_config.service_channels[channel_index].nb_subchannels.erfsn = new_full_unit_config.channels_configuration.service_channels[channel_index].service_subchannels.earfcn
                current_full_unit_config.service_channels[channel_index].nb_subchannels.channels[0] = new_full_unit_config.channels_configuration.service_channels[channel_index].service_subchannels.arfcns[0]
                current_full_unit_config.service_channels[channel_index].nb_subchannels.channels[1] = new_full_unit_config.channels_configuration.service_channels[channel_index].service_subchannels.arfcns[1]
                current_full_unit_config.service_channels[channel_index].nb_subchannels.channels[2] = new_full_unit_config.channels_configuration.service_channels[channel_index].service_subchannels.arfcns[2]
                current_full_unit_config.service_channels[channel_index].nb_subchannels.channels[3] = new_full_unit_config.channels_configuration.service_channels[channel_index].service_subchannels.arfcns[3]

        if current_full_unit_config.unit_configuration.unit_type == BlockType.FSC:
            for index in range(0, 4):
                current_full_unit_config.service_channels[index].attenuation.ul = 0
                current_full_unit_config.service_channels[index].attenuation.dl = new_full_unit_config.channels_configuration.service_channels[index].fields.attenuation.attenuation_dl
        else:
            for index in range(0, 4):
                if new_full_unit_config.channels_configuration.service_channels[index].fields.delay is None:
                    delay_ul = 0
                    delay_dl = 0
                else:
                    delay_ul = new_full_unit_config.channels_configuration.service_channels[index].fields.delay.delay_ul
                    delay_dl = new_full_unit_config.channels_configuration.service_channels[index].fields.delay.delay_dl

                current_full_unit_config.service_channels[index].attenuation.ul = delay_ul
                current_full_unit_config.service_channels[index].attenuation.dl = delay_dl

        for channel_index in range(0, 4):
            if new_full_unit_config.channels_configuration.arfsn is None:
                arfsn_min = 0
                arfsn_max = 0
            else:
                arfsn_min = new_full_unit_config.channels_configuration.arfsn.min
                arfsn_max = new_full_unit_config.channels_configuration.arfsn.max

            current_full_unit_config.service_channels[channel_index].min_arfsn = arfsn_min
            current_full_unit_config.service_channels[channel_index].max_arfsn = arfsn_max

        return current_full_unit_config

    async def save_part_of_new_config(self, new_full_unit_config: NewFullUnitConfiguration):
        # ФРОНТ ПРИСЫЛАЕТ ИЛИ CHANNELS CONFIG, ИЛИ COMMON CONFIG. ЧТО ТО ИЗ НИХ БУДЕТ NONE
        # ИЗ-ЗА ЭТОГО В КОНФИГУ ЗАПИСЫВАЕТСЯ ПУСТОТА, ПО ЭТОМУ ТАМ ГДЕ NONE ДЕЛАЕМ ЗАПРОС НА ТЕКУЩУЮ КОНФИГУ
        # И ПОДСТАВЛЯЕМ ВМЕСТО NONE ТО, ЧТО ТАМ ЗАПИСАНО СЕЙЧАС

        current_new_full_unit_config = NewFullUnitConfiguration(**(await self.get_new_full_unit_config()))

        if new_full_unit_config.channels_configuration is None:

            new_full_unit_config.channels_configuration = current_new_full_unit_config.channels_configuration

        elif new_full_unit_config.common_configuration is None:

            new_full_unit_config.common_configuration = current_new_full_unit_config.common_configuration

        self.save_only_new_full_config(new_full_unit_config)

    async def set_new_full_unit_config(self, new_full_unit_config, user_role: str, upload_config: bool = False) -> ResponseMessage:
        new_full_unit_config = NewFullUnitConfiguration(**new_full_unit_config)

        await self.save_part_of_new_config(new_full_unit_config)

        armyanskiy_full_unit_config = await self.SI_API.get_full_configuration()

        if new_full_unit_config.channels_configuration is not None and new_full_unit_config.common_configuration is not None:

            armyanskiy_full_unit_config = self.set_convert_channel_config(armyanskiy_full_unit_config, new_full_unit_config, user_role)
            armyanskiy_full_unit_config = self.set_convert_common_config(armyanskiy_full_unit_config, new_full_unit_config, user_role, upload_config)

        elif new_full_unit_config.channels_configuration is not None:

            armyanskiy_full_unit_config = self.set_convert_channel_config(armyanskiy_full_unit_config, new_full_unit_config, user_role)

        elif new_full_unit_config.common_configuration is not None:

            armyanskiy_full_unit_config = self.set_convert_common_config(armyanskiy_full_unit_config, new_full_unit_config, user_role)

        await self.SI_API.set_full_configuration(armyanskiy_full_unit_config, user_role)

        return ResponseMessage(message='Configuration saved', status=True)

    def convert_old_block_mode_to_new(self, block_mode):
        if block_mode == ChanelConfig.LTE:
            return BlockMode.WB
        elif block_mode == ChanelConfig.LTE_GSM:
            return BlockMode.WB_2G
        elif block_mode == ChanelConfig.GSM:
            return BlockMode.G2

    def get_carrier_frequency_flag(self, service_channels: list) -> CarrierFrequencyResponse:

        sm_1_enabled, sm_2_enabled, sm_3_enabled, sm_4_enabled = (service_channels[0].str.enabled,
                                                                  service_channels[1].str.enabled,
                                                                  service_channels[2].str.enabled,
                                                                  service_channels[3].str.enabled)

        carrier_frequency_status_1, carrier_frequency_status_2 = None, None

        if sm_1_enabled or sm_2_enabled:
            carrier_frequency_status_1 = True
        elif sm_1_enabled is False or sm_2_enabled is False:
            carrier_frequency_status_1 = False
        elif sm_1_enabled is None and sm_2_enabled is None:
            carrier_frequency_status_1 = None

        if sm_3_enabled or sm_4_enabled:
            carrier_frequency_status_2 = True
        elif sm_3_enabled is False or sm_4_enabled is False:
            carrier_frequency_status_2 = False
        elif sm_3_enabled is None and sm_4_enabled is None:
            carrier_frequency_status_2 = None

        return CarrierFrequencyResponse(status_1=carrier_frequency_status_1, status_2=carrier_frequency_status_2)

    def get_relay_channel_connection_status(self, rm_1_status: bool | None, rm_2_status: bool | None,
                                            sfp_1_status: bool | None, sfp_2_status: bool | None) -> RelayChannelConnectionStatusResponse:

        if rm_1_status in [True, False]:
            connection_type_1_status = ConnectionType.RADIO
        elif sfp_1_status is True:
            connection_type_1_status = ConnectionType.OPTICS
        else:
            connection_type_1_status = ConnectionType.EMPTY

        if rm_2_status in [True, False]:
            connection_type_2_status = ConnectionType.RADIO
        elif sfp_2_status is True:
            connection_type_2_status = ConnectionType.OPTICS
        else:
            connection_type_2_status = ConnectionType.EMPTY

        return RelayChannelConnectionStatusResponse(status_1=connection_type_1_status,
                                                    status_2=connection_type_2_status)

    def get_channels_enabled_status(self, configuration: NewFullUnitConfiguration):
        rm_1_enabled = configuration.channels_configuration.relay_channels[0].enabled
        rm_2_enabled = configuration.channels_configuration.relay_channels[1].enabled

        sm_1_enabled = configuration.channels_configuration.service_channels[0].enabled
        sm_2_enabled = configuration.channels_configuration.service_channels[1].enabled
        sm_3_enabled = configuration.channels_configuration.service_channels[2].enabled
        sm_4_enabled = configuration.channels_configuration.service_channels[3].enabled

        return rm_1_enabled, rm_2_enabled, sm_1_enabled, sm_2_enabled, sm_3_enabled, sm_4_enabled

    def get_real_sm_and_rm_and_subchannels_statuses(self, new_full_unit_config: NewFullUnitConfiguration, saved_not_modified_config: NewFullUnitConfiguration) -> NewFullUnitConfiguration:

        rm_1_enabled, rm_2_enabled, sm_1_enabled, sm_2_enabled, sm_3_enabled, sm_4_enabled = self.get_channels_enabled_status(saved_not_modified_config)

        new_full_unit_config.channels_configuration.relay_channels[0].enabled = rm_1_enabled if rm_1_enabled is None else new_full_unit_config.channels_configuration.relay_channels[0].enabled
        new_full_unit_config.channels_configuration.relay_channels[1].enabled = rm_2_enabled if rm_2_enabled is None else new_full_unit_config.channels_configuration.relay_channels[1].enabled

        new_full_unit_config.channels_configuration.service_channels[0].enabled = sm_1_enabled if sm_1_enabled is None else new_full_unit_config.channels_configuration.service_channels[0].enabled
        new_full_unit_config.channels_configuration.service_channels[1].enabled = sm_2_enabled if sm_2_enabled is None else new_full_unit_config.channels_configuration.service_channels[1].enabled
        new_full_unit_config.channels_configuration.service_channels[2].enabled = sm_3_enabled if sm_3_enabled is None else new_full_unit_config.channels_configuration.service_channels[2].enabled
        new_full_unit_config.channels_configuration.service_channels[3].enabled = sm_4_enabled if sm_4_enabled is None else new_full_unit_config.channels_configuration.service_channels[3].enabled

        return new_full_unit_config

    def pop_attenuation_and_subchannels(self, new_full_unit_config: dict) -> dict:

        # ПОЛУЧАЕМ СЕРИВСНЫЕ КАНАЛЫ
        service_channels = new_full_unit_config.get('channels_configuration').get('service_channels')

        # В ЗАВИСИМОСТИ ОТ ТИПА ПОЛЯ УДАЛЯЕМ НЕ НУЖНЫЙ DELAY ДЛЯ FSR ИЛИ ATTENUATION ДЛЯ FSC
        for index, channel in enumerate(service_channels):
            attenuation_or_delay = 'delay' if type(channel.get('fields').get('attenuation')) is dict else 'attenuation'
            channel.get('fields').pop(attenuation_or_delay)

            # В 0 И 1 ИНДЕКСЕ СЕРВИСНЫХ КАНАЛОВ НЕ НУЖНЫ САБКАНАЛЫ
            if index in [0, 1]:
                channel.pop('service_subchannels')

        # ЗАМЕНЯЕМ ТЕКУЩИЕ СЕРВИСНЫЕ КАНАЛЫ НА НОВЫЕ
        new_full_unit_config.get('channels_configuration')['service_channels'] = service_channels

        return new_full_unit_config

    async def get_new_full_unit_config(self) -> dict | ResponseMessage:
        current_full_unit_config, new_full_unit_config = await self.SI_API.get_full_configuration(), NewFullUnitConfiguration()

        saved_not_modified_config = self.load_new_full_config()

        new_full_unit_config.channels_configuration = ChannelsConfiguration()
        new_full_unit_config.common_configuration = CommonConfiguration()

        carrier_frequency_statuses = self.get_carrier_frequency_flag(current_full_unit_config.service_channels)

        rm_1_status, rm_2_status = saved_not_modified_config.channels_configuration.relay_channels[0].enabled, saved_not_modified_config.channels_configuration.relay_channels[1].enabled
        sfp_1_status, sfp_2_status = saved_not_modified_config.common_configuration.sfp_statuses.sfp_1_enabled, saved_not_modified_config.common_configuration.sfp_statuses.sfp_2_enabled

        relay_channel_connection_status = self.get_relay_channel_connection_status(rm_1_status, rm_2_status, sfp_1_status, sfp_2_status)

        rm_1_enabled_status, rm_2_enabled_status = current_full_unit_config.relay_channels[0].rtr_common.rt_rxs_enabled[0], current_full_unit_config.relay_channels[0].rtr_common.rt_rxs_enabled[1]

        # CHANNELS_CONFIGURATION
        new_full_unit_config.channels_configuration.auto_gain_enabled = current_full_unit_config.unit_configuration.ac_link_tx
        new_full_unit_config.channels_configuration.block_mode = self.convert_old_block_mode_to_new(current_full_unit_config.unit_configuration.channel_3_and_4_config)

        # ВЫСТАВЛЯЕМ НЕСУЩУЮ ЧАСТОТУ. В СТАРОМ КОНФИГЕ ПИШЕМ В НУЛЕВОЙ И ВТОРОЙ СМ
        for index in range(0, 2):
            new_full_unit_config.channels_configuration.carrier_frequency[index].enabled = carrier_frequency_statuses.status_1 if index == 0 else carrier_frequency_statuses.status_2
            new_full_unit_config.channels_configuration.carrier_frequency[index].fields.carrier_frequency_ul = current_full_unit_config.service_channels[index * 2].str.carrier_frequency.ul
            new_full_unit_config.channels_configuration.carrier_frequency[index].fields.carrier_frequency_dl = current_full_unit_config.service_channels[index * 2].str.carrier_frequency.dl

        rm_enabled_statuses = [rm_1_enabled_status if relay_channel_connection_status.status_1 == ConnectionType.RADIO else None,
                               rm_2_enabled_status if relay_channel_connection_status.status_2 == ConnectionType.RADIO else None]

        rm_connection_statuses = [relay_channel_connection_status.status_1, relay_channel_connection_status.status_2]

        statuses = _get_statuses_list_by_cviya(service_channel_3_enabled=current_full_unit_config.service_channels[2].str.enabled,
                                                           service_channel_4_enabled=current_full_unit_config.service_channels[3].str.enabled,
                                                           block_type=current_full_unit_config.unit_configuration.unit_type,
                                                           block_cviya=current_full_unit_config.unit_configuration.cviya,
                                                           block_mode=self.convert_old_block_mode_to_new(current_full_unit_config.unit_configuration.channel_3_and_4_config))

        if type(statuses) is ResponseMessage:
            return statuses

        # ПРОХОД ПО РМАМ
        for relay_channel_index in range(0, 2):
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].enabled = rm_enabled_statuses[relay_channel_index]
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].connection_type = rm_connection_statuses[relay_channel_index]
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].fields.central_frequency_rx = current_full_unit_config.relay_channels[0].rtrs[relay_channel_index].central_frequency.dl
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].fields.central_frequency_tx = current_full_unit_config.relay_channels[0].rtrs[relay_channel_index].central_frequency.ul
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].fields.input_gain = current_full_unit_config.relay_channels[0].rtrs[relay_channel_index].output_power_link.input_gain
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].fields.output_gain = current_full_unit_config.relay_channels[0].rtrs[relay_channel_index].output_power_link.output_gain
            new_full_unit_config.channels_configuration.relay_channels[relay_channel_index].fields.output_power = current_full_unit_config.relay_channels[0].rtrs[relay_channel_index].output_power_link.output_power

        # В ЗАВИСИМОСТИ ОТ ТИПА БЛОКА РАЗНОЕ ПОЛЕ, DELAY ДЛЯ FSR ИЛИ ATTENUATION ДЛЯ FSC
        # НО В СТАРОМ JSONE ВСЁ ЛЕЖИТ В ПОЛЕ ATTENUATION
        if current_full_unit_config.unit_configuration.unit_type == BlockType.FSC:
            for index in range(0, 4):
                new_full_unit_config.channels_configuration.service_channels[index].fields.attenuation = Attenuation()
                new_full_unit_config.channels_configuration.service_channels[index].fields.attenuation.attenuation_ul = None
                new_full_unit_config.channels_configuration.service_channels[index].fields.attenuation.attenuation_dl = current_full_unit_config.service_channels[index].attenuation.dl
        else:
            for index in range(0, 4):
                new_full_unit_config.channels_configuration.service_channels[index].fields.delay = Delay()
                new_full_unit_config.channels_configuration.service_channels[index].fields.delay.delay_ul = current_full_unit_config.service_channels[index].attenuation.ul
                new_full_unit_config.channels_configuration.service_channels[index].fields.delay.delay_dl = current_full_unit_config.service_channels[index].attenuation.dl

        # ПРОХОД ПО СМАМ
        for index in range(0, 4):
            new_full_unit_config.channels_configuration.service_channels[index].editable = current_full_unit_config.service_channels[index].editable
            new_full_unit_config.channels_configuration.service_channels[index].enabled = current_full_unit_config.service_channels[index].str.enabled
            new_full_unit_config.channels_configuration.service_channels[index].frequency = current_full_unit_config.service_channels[index].frequency
            new_full_unit_config.channels_configuration.service_channels[index].fields.bandwidth = current_full_unit_config.service_channels[index].bandwidth
            new_full_unit_config.channels_configuration.service_channels[index].fields.bs_power = current_full_unit_config.service_channels[index].str.output_power
            new_full_unit_config.channels_configuration.service_channels[index].fields.frequency_offset.frequency_offset_ul = current_full_unit_config.service_channels[index].frequency_offset.ul
            new_full_unit_config.channels_configuration.service_channels[index].fields.gain.gain_ul = current_full_unit_config.service_channels[index].str.gain.ul
            new_full_unit_config.channels_configuration.service_channels[index].fields.gain.gain_dl = current_full_unit_config.service_channels[index].str.gain.dl

            # ДЛЯ ТРЕТЬЕГО И ЧЕТВЁРТОГО СМА ДОБАВЛЯЕМ САБ КАНАЛЫ
            if index > 1:
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels = ServiceSubChannels()

                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.earfcn = current_full_unit_config.service_channels[index].nb_subchannels.erfsn
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.enabled_arfcn = new_full_unit_config.channels_configuration.service_channels[index].enabled
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.arfcns[0] = current_full_unit_config.service_channels[index].nb_subchannels.channels[0]
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.arfcns[1] = current_full_unit_config.service_channels[index].nb_subchannels.channels[1]
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.arfcns[2] = current_full_unit_config.service_channels[index].nb_subchannels.channels[2]
                new_full_unit_config.channels_configuration.service_channels[index].service_subchannels.arfcns[3] = current_full_unit_config.service_channels[index].nb_subchannels.channels[3]

        # У ВТОРОГО И ТРЕТЬЕГО СМА ЕСТЬ СТАТУСЫ EARFCN.
        # БЕРЁМ ИХ ИЗ СПИСКА ПО ИНДЕКСУ НОЛЬ ДЛЯ ТРЕТЬЕГО СМА И ИНДЕКС ОДИН ДЛЯ ЧЕТВЁРТОГО СМА
        for service_channel_index in range(2, 4):
            new_full_unit_config.channels_configuration.service_channels[service_channel_index].service_subchannels.enabled_earfcn = statuses.earfcn_statuses_list[service_channel_index - 2]

        # САБ КАНАЛЫ
        for index in range(0, 4):
            new_full_unit_config.channels_configuration.subchannels[index].enabled = current_full_unit_config.relay_channels[index].rtr_common.enabled.ul
            new_full_unit_config.channels_configuration.subchannels[index].fields.bandwidth.bandwidth_ul = current_full_unit_config.relay_channels[index].rtr_common.bandwidth.ul
            new_full_unit_config.channels_configuration.subchannels[index].fields.frequency_offset.frequency_offset_ul = current_full_unit_config.relay_channels[index].rtr_common.frequency_offset.ul

        #COMMON_CONFIGURATION
        new_full_unit_config.common_configuration.alarm_config.modem_alarm = current_full_unit_config.alarm_config.modem_alarm
        new_full_unit_config.common_configuration.alarm_config.server_alarm = current_full_unit_config.alarm_config.server_alarm
        new_full_unit_config.common_configuration.alarm_config.sensor_1_enabled = current_full_unit_config.alarm_config.sensors[0].enabled
        new_full_unit_config.common_configuration.alarm_config.sensor_1_normal_state = current_full_unit_config.alarm_config.sensors[0].normal_state
        new_full_unit_config.common_configuration.alarm_config.sensor_2_enabled = current_full_unit_config.alarm_config.sensors[1].enabled
        new_full_unit_config.common_configuration.alarm_config.sensor_2_normal_state = current_full_unit_config.alarm_config.sensors[1].normal_state

        new_full_unit_config.common_configuration.sfp_statuses.sfp_1_enabled = current_full_unit_config.alarm_config.sfp[0]
        new_full_unit_config.common_configuration.sfp_statuses.sfp_2_enabled = current_full_unit_config.alarm_config.sfp[1]

        new_full_unit_config.common_configuration.block_config.block_info.block_name = current_full_unit_config.unit_configuration.block_name
        new_full_unit_config.common_configuration.block_config.block_info.mac_address = current_full_unit_config.unit_configuration.main_module.mac_address
        new_full_unit_config.common_configuration.block_config.block_info.serial_number = current_full_unit_config.unit_configuration.main_module.serial_number
        new_full_unit_config.common_configuration.block_config.block_info.version_info = current_full_unit_config.unit_configuration.version_info

        new_full_unit_config.common_configuration.block_config.config.block_ip = current_full_unit_config.unit_configuration.device.ip
        new_full_unit_config.common_configuration.block_config.config.block_port = current_full_unit_config.unit_configuration.device.port
        new_full_unit_config.common_configuration.block_config.config.gateway = current_full_unit_config.unit_configuration.device.gateway
        new_full_unit_config.common_configuration.block_config.config.netmask = current_full_unit_config.unit_configuration.device.netmask
        new_full_unit_config.common_configuration.block_config.config.server_ip = current_full_unit_config.unit_configuration.server.ip
        new_full_unit_config.common_configuration.block_config.config.server_port = current_full_unit_config.unit_configuration.server.port

        new_full_unit_config.common_configuration.block_config.modem_config.apn = current_full_unit_config.modem.apn
        new_full_unit_config.common_configuration.block_config.modem_config.password = current_full_unit_config.modem.password
        new_full_unit_config.common_configuration.block_config.modem_config.ping_address = current_full_unit_config.modem.ping_address
        new_full_unit_config.common_configuration.block_config.modem_config.sim_ip = current_full_unit_config.modem.sim_ip
        new_full_unit_config.common_configuration.block_config.modem_config.user = current_full_unit_config.modem.user

        new_full_unit_config.common_configuration.block_cviya = current_full_unit_config.unit_configuration.cviya
        new_full_unit_config.common_configuration.block_type = current_full_unit_config.unit_configuration.unit_type
        new_full_unit_config.common_configuration.timezone = current_full_unit_config.unit_configuration.timezone

        calibration_history: CalibrateHistory = load_config('ac/last_calibrate_history', CalibrateHistory, CalibrateHistory())

        new_full_unit_config.common_configuration.calibration_config.last_calibration_date = calibration_history.date.timestamp() if calibration_history.date is not None else None
        new_full_unit_config.common_configuration.calibration_config.calibration_state = current_full_unit_config.unit_configuration.calibration_state
        new_full_unit_config.common_configuration.calibration_config.simulation_state = current_full_unit_config.unit_configuration.simulation_state
        new_full_unit_config.common_configuration.calibration_config.ustirovka_state = current_full_unit_config.unit_configuration.ustirovka_state

        new_full_unit_config.channels_configuration.arfsn.min = current_full_unit_config.service_channels[0].min_arfsn
        new_full_unit_config.channels_configuration.arfsn.max = current_full_unit_config.service_channels[0].max_arfsn

        # НЕЛЬЗЯ NONE В ПОЛЯХ ВКЛЮЧЕНИЯ РМОВ И СМОВ И САБ КАНАЛОВ, ВМЕСТО NONE ТАМ ЛЕЖИТ FALSE
        # ИЗ ЗА ЭТОГО НУЖНО ДЕЛАТЬ ПЕРЕКАСТ В NONE ДЛЯ НОВОГО ФРОНТА
        config_with_new_front_statuses = self.get_real_sm_and_rm_and_subchannels_statuses(new_full_unit_config, saved_not_modified_config)

        final_config = self.change_modes(config_with_new_front_statuses, config_with_new_front_statuses.channels_configuration.block_mode)

        return final_config

    async def get_gps_time(self) -> GpsTime:
        timezone: int = (await self.SI_API.get_full_configuration()).unit_configuration.timezone
        timestamp = (datetime.now() + timedelta(hours=timezone)).timestamp()
        gps_string = load_const('gps_position', str, None)

        if gps_string is not None:
            prom_split = gps_string.split(' ')
            prom_split.pop(2)
            gps_string = ' '.join(prom_split)

        return GpsTime(timestamp=timestamp,
                       gps_string=gps_string,
                       timezone=timezone)

    async def set_gps_time(self, gps_time: GpsTime) -> bool:
        try:
            await self.SI_API.set_current_time(gps_time.timestamp)
            await self.SI_API.set_gps_position(gps_time.gps_string)

            armyanskiy_full_unit_config: FullUnitConfiguration = await self.SI_API.get_full_configuration()
            armyanskiy_full_unit_config.unit_configuration.timezone = gps_time.timezone
            await self.SI_API.set_full_configuration(armyanskiy_full_unit_config)

            return True
        except Exception as e:
            return False

    def delete_alarms(self, alarms_to_be_deleted: DeleteAlarms) -> ResponseMessage:
        try:
            if alarms_to_be_deleted.alarm_type == 'log':
                self.alarm_db.delete_log_alarm(aids=alarms_to_be_deleted.ids)

            else:

                alarm: Alarm
                current_alarms: List[Optional[Alarm]] = load_config('si/current_alarms', List[Optional[Alarm]], [None] * len(ALARMS))
                if len(current_alarms) < len(ALARMS):
                    delta = len(ALARMS) - len(current_alarms)
                    current_alarms.extend([None] * delta)

                current_alarms_copy: List[Optional[Alarm]] = current_alarms.copy()

                alarm_id: int
                for alarm_id in alarms_to_be_deleted.ids:
                    for index, alarm in enumerate(current_alarms_copy):
                        if alarm is not None:
                            if alarm.aid == alarm_id:
                                current_alarms[index] = None

                save_config('si/current_alarms', current_alarms)

            return ResponseMessage(message='Аварии удалены!', status=True)

        except Exception as e:
            return ResponseMessage(message='Ошибка при удалении аварий!', status=False)
